using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Resources;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;

using System.Runtime.InteropServices;
using System.Diagnostics;


namespace SypConst.Garbage
{
    public delegate void SetText(object msg, Output output);

    public enum ConnectionMode : ushort
    {
        DIRECT_MODE = 2,
        FTP_MODE = 1,
        SCP_MODE = 0
    }


    public enum Output : ushort
    {
        JSON = 17,
        
        LOCK = 15,
        UNLOCK = 14,

        /* Progressing Flag */
        PROGRESS_RESET_POS = 13,
        PROGRESS_POS = 11,


        /* Online synchronise Flag */
        ONLINE_ALL_DONE = 10,
        ONLINE_DONE = 9,
        ONLINE_STEP = 8,

        /* Local synchronise Flag */
        LOCAL_DONE = 5,
        LOCAL_STEP = 4,

        /* Output Flag */
        COMMAND = 2,
        ERROR = 1,
        OUT = 0
    }


    [Serializable]
    public struct TransferConf
    {
        public string Hostname;
        public int Port;
        public string Password;
        public string Login;
        public string RemoteDir;
        public int PassiveMode;
    }


    public class SypGarbage
    {

        #region Constants

        //Firefox Profile
        public const string FIREFOX_PROFILE_PATH = @"\Mozilla\Firefox\Profiles";
        public const string FIREFOX_PROFILE_FOLDER_FILTER = ".default";
        public const string FIREFOX_CONFIG_FILE = "prefs.js";
        public const string FIREFOX_SECURITY_POLICY = "user_pref('security.fileuri.strict_origin_policy', false);";
        
        //Assembly name
        public const string ASSEMBLY_NAME = "SypAgent.exe";
        
        //About Syp Link
        public const string ABOUT_SYP_LNK = "http://www.shareyourpicture.org/whatissyp";

        //Jpeg Compression Thumbnail
        public const long JPEG_COMPRESSION_QUALITY_THUMB = 50;

        //Jpeg Compression Picture
        public const long JPEG_COMPRESSION_QUALITY_ORIGINAL = 65;

        //Http url prefix :
        public const string HTTP_PREFIX = "http://";

        //Syp default port
        public const int SYP_DEFAULT_PORT = 5000;

        //Syp default publishing interval (in minutes)
        public const int SYP_DEFAULT_PUBLISHING_INTERVAL = 15;

        //Syp default synchronizing interval (in minutes)
        public const int SYP_DEFAULT_SYNCRHONIZING_INTERVAL = 10;

        //Culture key
        public const string SYP_CULTURE_FRENCH = "fr-FR";
        public const string SYP_CULTURE_US = "en-US";

        //General conf file
        public const string SYP_GENERAL_CONF_FILE = "syp.xml";

        // ID init value
        //public const int INIT_ID = 42;

        //Timer interval for synchronisings (ms)
        public const int PUBLISHING_INTERVAL = 60 * 1000;

        //Timer interval for auto-synchronisings (ms)
        public const int AUTO_SYNCHRONIZING_INTERVAL = 75 * 1000;


        //Menu Item title maxlength
        public const int ITEM_MAX_LENGTH = 30;

        //default FTP PORT
        public const string FTP_DEFAULT_PORT = "21";
       
        
        //default Navigator
        //public const string BROWSER = @"C:\Program Files\Internet Explorer\IEXPLORE.exe";
        public const string FIREFOX_BROWSER_REGPATH = @"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe";
        public const string CHROME_BROWSER_REGPATH = @"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe";
        
        //Console
        public const int CONSOLE_HISTORY_SIZE = 50;
        
        //Special characters
        public const string RETURN = "\r\n";
        public const string SSH_RETURN = "\n";

        public const char COMMAND_SEPARATOR = ' ';
        //public const string SEPARATOR = ';';
        public const char SUB_COMMAND_SEPARATOR = '-';

        //debug variable
        public const bool DEBUG = true;
        public const bool FREE = true;
        public static bool SLIDESHOW = false;

        //Pictures filter
        public const string PICTURE_FILTER = "*.jpg;*.jpeg;*.png;*.gif";

        //Picture Features
        public const int THUMBNAIL_WIDTH = 185;
        public const int THUMBNAIL_HEIGHT = 148;


        public const int PICTURE_WIDTH = 640;
        public const int PICTURE_HEIGHT = 480;

        //console nb line
        public const int SYP_SHELL_NB_LINE = 7;

        #endregion


        #region tool static methods



        public static void free(Object obj)
        {
            if (FREE)
            {
                obj = null;
                //GC.Collect();
                //GC.WaitForPendingFinalizers();
            }
        }

        public static bool IsUsed(int Id, ref List<int> UsedIdList)
        {
            foreach (int elt in UsedIdList)
            {
                if (elt.Equals(Id))
                    return true;
            }
            return false;
        }

        public static void ProcessKill(string processName)
        {
            Process[] SypProcesses = Process.GetProcessesByName(processName);
            foreach (Process p in SypProcesses)
            {
                p.Kill();
            }
        }

        public static void ProcessLauncher(string processName, string arguments)
        {
            Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = processName;
            if (!string.IsNullOrEmpty(arguments))
                p.StartInfo.Arguments = arguments;
            p.Start();
        }

        public static bool SearchIntoFile(string filepath, string searchpattern)
        {
            StreamReader testTxt = new StreamReader(filepath);

            if (testTxt != null)
            {
                string allRead = testTxt.ReadToEnd();
                testTxt.Close();
                string regMatch = searchpattern;

                if (Regex.IsMatch(allRead, regMatch))
                    return true;
            }
            return false;
        }

        /*public static int GenerateId(ref List<int> UsedIdList)
        {
            Random REngine = new Random();
            int RandomId = REngine.Next();
            while (UsedIdList != null && IsUsed(RandomId, ref UsedIdList))
                RandomId = REngine.Next();
            if (UsedIdList == null)
                UsedIdList = new List<int>();
            UsedIdList.Add(RandomId);
            return RandomId;
        }*/

        public static string GetFileName(string absolutePath)
        {
            FileInfo fi = new FileInfo(absolutePath);
            return fi.Name;
            
            /*string[] subdirs = absolutePath.Split(new char[] { '/' });
            if (subdirs.Length == 1)
            {
                subdirs = absolutePath.Split(new char[] { '\\' });
            }
            string[] subdirs2 = subdirs[subdirs.Length - 1].Split(new char[] { '\\' });
            return subdirs2[subdirs2.Length - 1];*/
        }

        public static string GetDirectoryName(string absolutePath)
        {
            string[] subdirs = absolutePath.Split(new char[] { '/' });
            if (subdirs.Length == 1)
            {
                subdirs = absolutePath.Split(new char[] { '\\' });
            }
            string[] subdirs2 = subdirs[subdirs.Length - 1].Split(new char[] { '\\' });
            return subdirs2[subdirs2.Length - 2];
        }

        public static bool CheckPictureFile(string filename)
        {
            string[] AllowedExtension = SypGarbage.PICTURE_FILTER.Split(new char[] { ',' });

            foreach (string ext in AllowedExtension)
            {
                if (File.Exists(filename))
                {
                    FileInfo pictureInfo = new FileInfo(filename);
                    if (pictureInfo.Extension.ToLower().Equals("." + ext.Trim()))
                        return true;
                }
            }
            return false;
        }

        public static string[] GetFiles(
                                string path,
                                string searchPattern)
        {
            string[] m_arExt = searchPattern.Split(';');

            List<string> strFiles = new List<string>();
            foreach (string filter in m_arExt)
            {
                strFiles.AddRange(
                       Directory.GetFiles(path, filter));
            }
            return strFiles.ToArray();
        }



        public static SypGarbageConf LoadSypConf()
        {
            FileStream fs = null;
            if (File.Exists(SypGarbage.SYP_GENERAL_CONF_FILE))
                fs = new FileStream(SypGarbage.SYP_GENERAL_CONF_FILE, FileMode.Open);
            else
                fs = new FileStream(SypGarbage.SYP_GENERAL_CONF_FILE, FileMode.Create);

            try
            {
                SypGarbageConf myConf = null;
                //BinaryFormatter formatter = new BinaryFormatter();
                XmlSerializer formatter = new XmlSerializer(typeof(SypGarbageConf));

                if (!File.Exists(SypGarbage.SYP_GENERAL_CONF_FILE))
                {
                    myConf = SypGarbageConf.Instance();
                    formatter.Serialize(fs, myConf);
                }
                else
                {
                    fs.Position = 0;
                    myConf = (SypGarbageConf)formatter.Deserialize(fs);
                }
                return myConf;
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                fs.Close();
            }
        }

        public static void SaveSypConf()
        {
            FileStream fs = null;

            try
            {
                //BinaryFormatter formatter = new BinaryFormatter();
                fs = new FileStream(SypGarbage.SYP_GENERAL_CONF_FILE, FileMode.Create);
                XmlSerializer formatter = new XmlSerializer(typeof(SypGarbageConf));
                formatter.Serialize(fs, SypGarbageConf.Instance());
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                throw;
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
        }

        #endregion
    }


       
}
